package com.funsport.controller.mobile;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.funsport.common.Result;
import com.funsport.common.enums.UserRole;
import com.funsport.common.enums.UserStatus;
import com.funsport.dto.request.WeChatLoginRequest;
import com.funsport.dto.response.LoginResponse;
import com.funsport.entity.User;
import com.funsport.security.JwtTokenProvider;
import com.funsport.service.IUserService;
import com.funsport.util.WeChatUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 移动端认证Controller
 *
 * @author Fun-Sport Team
 */
@Slf4j
@Tag(name = "移动端认证", description = "移动端用户认证相关接口")
@RestController
@RequestMapping("/mobile/auth")
@RequiredArgsConstructor
public class MobileAuthController {

    private final IUserService userService;
    private final JwtTokenProvider jwtTokenProvider;
    private final WeChatUtil weChatUtil;

    /**
     * 微信小程序登录
     */
    @Operation(summary = "微信小程序登录", description = "使用微信code进行登录，如果用户不存在则自动注册")
    @PostMapping("/wechat/login")
    public Result<LoginResponse> wechatLogin(@Valid @RequestBody WeChatLoginRequest request) {
        String codePrefix = request.getCode() != null ? 
            request.getCode().substring(0, Math.min(10, request.getCode().length())) : "null";
        log.info("=== 收到微信登录请求 ===");
        log.info("code前缀: {}, nickname: {}", codePrefix, request.getNickname());

        try {
            // 调用微信API获取openid和unionid
            Map<String, String> wechatInfo = weChatUtil.getWeChatOpenId(request.getCode());
            if (wechatInfo == null) {
                log.error("微信API调用失败，返回null");
                return Result.error(500, "微信登录失败，请重试");
            }

            String openid = wechatInfo.get("openid");
            String unionid = wechatInfo.get("unionid");
            
            if (openid == null || openid.trim().isEmpty()) {
                log.error("微信API返回的openid为空");
                return Result.error(500, "微信登录失败，请重试");
            }
            
            log.info("微信API调用成功，openid前缀: {}", openid.substring(0, Math.min(10, openid.length())));

            // 查询用户是否存在
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .eq(User::getOpenid, openid));

            if (user == null) {
                // 新用户，自动注册
                log.info("新用户注册，openid前缀: {}", openid.substring(0, Math.min(10, openid.length())));
                
                user = new User();
                user.setOpenid(openid);
                user.setUnionid(unionid);
                user.setNickname(request.getNickname() != null ? request.getNickname() : "用户" + System.currentTimeMillis());
                user.setAvatar(request.getAvatar());
                user.setGender(request.getGender() != null ? request.getGender() : 0);
                user.setRole(UserRole.CUSTOMER);
                user.setStatus(UserStatus.ACTIVE);
                user.setPoints(0);
                user.setLevel(1);
                
                userService.save(user);
                log.info("新用户注册成功: userId={}, nickname={}", user.getId(), user.getNickname());
            } else {
                // 老用户，只更新最后登录时间
                log.info("老用户登录: userId={}, nickname={}", user.getId(), user.getNickname());
                
                // 【重要】老用户登录时，不要自动更新nickname和avatar
                // 因为用户可能已经在个人信息页面自定义了昵称和头像
                // 如果每次登录都用微信的默认信息覆盖，会导致用户自定义的信息丢失
                
                // 只更新最后登录时间
                user.setLastLoginAt(LocalDateTime.now());
                userService.updateById(user);
                
                log.info("老用户登录成功，保留原有昵称: {}", user.getNickname());
            }

            // 生成JWT Token
            String token = jwtTokenProvider.generateToken(user.getId(), user.getRole().getValue());
            log.info("JWT Token生成成功，用户ID: {}", user.getId());

            // 构建完整的用户信息
            LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
            userInfo.setId(user.getId());
            userInfo.setRole(user.getRole().getValue());
            userInfo.setNickname(user.getNickname());
            userInfo.setAvatar(user.getAvatar());
            userInfo.setGender(user.getGender());
            userInfo.setPhone(user.getPhone());
            userInfo.setEmail(user.getEmail());
            userInfo.setCity(user.getCity());
            userInfo.setDistrict(user.getDistrict());
            userInfo.setBio(user.getBio());
            userInfo.setSportsPreferences(user.getSportsPreferences());
            userInfo.setSkillLevel(user.getSkillLevel());
            userInfo.setPoints(user.getPoints());
            userInfo.setLevel(user.getLevel());

            LoginResponse response = new LoginResponse(token, userInfo);

            log.info("=== 登录成功，返回响应（包含完整用户信息）===");
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("微信登录过程中发生异常", e);
            return Result.error(500, "登录失败：" + e.getMessage());
        }
    }

    /**
     * 用户名密码登录
     */
    @Operation(summary = "用户名密码登录", description = "使用用户名和密码进行登录")
    @PostMapping("/login")
    public Result<LoginResponse> login(@Valid @RequestBody com.funsport.dto.request.WebLoginRequest request) {
        log.info("=== 收到用户名密码登录请求 ===");
        log.info("username: {}", request.getUsername());

        try {
            // 支持多种方式登录：手机号、邮箱、昵称
            User user = userService.getOne(new LambdaQueryWrapper<User>()
                    .and(wrapper -> wrapper
                            .eq(User::getPhone, request.getUsername())
                            .or()
                            .eq(User::getEmail, request.getUsername())
                            .or()
                            .eq(User::getNickname, request.getUsername())));

            if (user == null) {
                log.warn("用户不存在: username={}", request.getUsername());
                return Result.error(401, "用户名或密码错误");
            }

            if (user.getPasswordHash() == null) {
                log.warn("用户未设置密码: userId={}", user.getId());
                return Result.error(401, "用户未设置密码，请联系管理员");
            }

            // 使用 PasswordEncoder 验证密码
            org.springframework.security.crypto.password.PasswordEncoder passwordEncoder = 
                new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();
            
            if (!passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
                log.warn("密码错误: userId={}", user.getId());
                return Result.error(401, "用户名或密码错误");
            }

            // 更新最后登录时间
            user.setLastLoginAt(LocalDateTime.now());
            userService.updateById(user);

            // 生成JWT Token
            String token = jwtTokenProvider.generateToken(user.getId(), user.getRole().getValue());
            log.info("JWT Token生成成功，用户ID: {}", user.getId());

            // 构建完整的用户信息
            LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
            userInfo.setId(user.getId());
            userInfo.setRole(user.getRole().getValue());
            userInfo.setNickname(user.getNickname());
            userInfo.setAvatar(user.getAvatar());
            userInfo.setGender(user.getGender());
            userInfo.setPhone(user.getPhone());
            userInfo.setEmail(user.getEmail());
            userInfo.setCity(user.getCity());
            userInfo.setDistrict(user.getDistrict());
            userInfo.setBio(user.getBio());
            userInfo.setSportsPreferences(user.getSportsPreferences());
            userInfo.setSkillLevel(user.getSkillLevel());
            userInfo.setPoints(user.getPoints());
            userInfo.setLevel(user.getLevel());

            LoginResponse response = new LoginResponse(token, userInfo);

            log.info("=== 登录成功，返回响应（包含完整用户信息）===");
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("登录过程中发生异常", e);
            return Result.error(500, "登录失败：" + e.getMessage());
        }
    }

    /**
     * 刷新Token
     */
    @Operation(summary = "刷新Token", description = "使用当前Token刷新获取新Token")
    @PostMapping("/refresh")
    public Result<LoginResponse> refreshToken() {
        // TODO: 实现Token刷新逻辑
        return Result.error("功能开发中");
    }
}

